package com.example.server;

import org.jgroups.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SysClusterServer extends ReceiverAdapter {

    Logger logger = LoggerFactory.getLogger(getClass());

    private JChannel channel;

    private String server_name;

    private String cluster_name = "default";

    private Address address;

    private View oldView;

    private SysClusterServerListener sysClusterServerListener;

    public void start() throws Exception {
        this.channel = new JChannel("jgroups-udp.xml");
        this.channel.setReceiver(this);
        this.channel.setName(server_name);
        this.channel.connect(cluster_name);
        this.address = this.channel.getAddress();
        logger.warn("节点: " + this.server_name + " 启动完毕 ...");
    }

    public void stop() {
        if (this.channel != null) {
            this.channel.disconnect();
            this.channel.close();
        }
    }

    public JChannel getChannel() {
        return this.channel;
    }

    public Address getAddress() {
        return this.address;
    }

    public void sendAll(Object message) throws Exception {
        this.channel.send(null, message);
    }

    public void sendTo(Address address, Object message) throws Exception {
        this.channel.send(address, message);
    }

    //消息监听
    @Override
    public void receive(Message msg) {
        this.sysClusterServerListener.receive(msg);
    }

    //节点上线监听
    public void up(Address address) {
        this.sysClusterServerListener.up(address);
    }

    //节点掉线监听
    public void down(Address address) {
        this.sysClusterServerListener.down(address);
    }

    @Override
    public void viewAccepted(View newView) {
        Address localAddress = this.getChannel().getAddress();
        java.util.List<Address> newMembers = newView.getMembers();
        if (oldView == null) {
            for (Address member : newMembers) {
                if (!member.equals(localAddress)) {
                    up(member);
                }
            }
        } else {
            java.util.List<Address> oldMembers = oldView.getMembers();
            for (Address member : newMembers) {
                if (!oldMembers.contains(member) && !member.equals(localAddress)) {
                    up(member);
                }
            }
            for (Address member : oldMembers) {
                if (!newMembers.contains(member) && !member.equals(localAddress)) {
                    down(member);
                }
            }
        }
        this.oldView = newView;
    }

    public SysClusterServer(String server_name, String cluster_name, SysClusterServerListener sysClusterServerListener) {
        this.server_name = server_name;
        this.cluster_name = cluster_name;
        this.sysClusterServerListener = sysClusterServerListener;
    }

    public SysClusterServer(String server_name, SysClusterServerListener sysClusterServerListener) {
        this.server_name = server_name;
        this.sysClusterServerListener = sysClusterServerListener;
    }

    public SysClusterServer(SysClusterServerListener sysClusterServerListener) {
        this.sysClusterServerListener = sysClusterServerListener;
    }

    ///////////////////////// set get/////////////////////////

    public void setChannel(JChannel channel) {
        this.channel = channel;
    }

    public String getServer_name() {
        return server_name;
    }

    public void setServer_name(String server_name) {
        this.server_name = server_name;
    }

    public String getCluster_name() {
        return cluster_name;
    }

    public void setCluster_name(String cluster_name) {
        this.cluster_name = cluster_name;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public View getOldView() {
        return oldView;
    }

    public void setOldView(View oldView) {
        this.oldView = oldView;
    }

    public SysClusterServerListener getSysClusterServerListener() {
        return sysClusterServerListener;
    }

    public void setSysClusterServerListener(SysClusterServerListener sysClusterServerListener) {
        this.sysClusterServerListener = sysClusterServerListener;
    }

    //定义回调处理的接口
    public interface SysClusterServerListener {

        //节点收到消息监听
        default public void receive(Message msg) {
        }

        //节点上线监听
        default public void up(Address address) {
        }

        //节点掉线监听
        default public void down(Address address) {
        }
    }
}
